﻿import type { RequestOptions } from "@@/plugin-request/request";
import type { RequestConfig } from "@umijs/max";
import { history } from "@umijs/max";
import { message, notification } from "antd";
const loginPath = "/user/login";
// 错误处理方案： 错误类型
enum ErrorShowType {
  SILENT = 0,
  WARN_MESSAGE = 1,
  ERROR_MESSAGE = 2,
  NOTIFICATION = 3,
  REDIRECT = 9,
}
// 与后端约定的响应数据格式
interface ResponseStructure {
  success: boolean;
  data: any;
  errorCode?: number;
  msg?: string;
  showType?: ErrorShowType;
  status?: number;
}

// 不需要添加 token 的接口列表
const EXCLUDE_PATHS = ["/login"];
/**
 * @name 错误处理
 * pro 自带的错误处理， 可以在这里做自己的改动
 * @doc https://umijs.org/docs/max/request#配置
 */
export const errorConfig: RequestConfig = {
  // 错误处理： umi@3 的错误处理方案。
  errorConfig: {
    // 错误抛出
    errorThrower: (res) => {
      const { success, data, errorCode, msg, showType, status } =
        res as unknown as ResponseStructure;
      if (!success) {
        let msgInfo = "";
        switch (status) {
          case 2:
            msgInfo = "账号或密码错误";
            break;
          case 9:
            msgInfo = "账号登录超时，请重新登录";
            break;
          case 3:
            msgInfo = "账户被禁用，请联系管理员";
            break;
          default:
            msgInfo = msg || "系统异常";
            break;
        }
        // error.name = "BizError";
        message.error(msgInfo);
        const error: any = new Error(msgInfo || msg || "系统异常");
        // error.info = { errorCode, errorMessage, showType, data };
        throw error; // 抛出自制的错误
      }
      // else {
      //   throw "系统异常";
      // }
    },
    // 错误接收及处理
    errorHandler: (error: any, opts: any) => {
      if (opts?.skipErrorHandler) throw error;
      // 我们的 errorThrower 抛出的错误。
      if (error.name === "BizError") {
        const errorInfo: ResponseStructure | undefined = error.info;
        if (errorInfo) {
          const { errorMessage, errorCode } = errorInfo;
          switch (errorInfo.showType) {
            case ErrorShowType.SILENT:
              // do nothing
              break;
            case ErrorShowType.WARN_MESSAGE:
              message.warning(errorMessage);
              break;
            case ErrorShowType.ERROR_MESSAGE:
              message.error(errorMessage);
              break;
            case ErrorShowType.NOTIFICATION:
              notification.open({
                description: errorMessage,
                message: errorCode,
              });
              break;
            case ErrorShowType.REDIRECT:
              // TODO: redirect
              break;
            default:
              message.error(errorMessage);
          }
        }
      } else if (error.response) {
        // Axios 的错误
        // 请求成功发出且服务器也响应了状态码，但状态代码超出了 2xx 的范围
        message.error(`Response status:${error.response.status}`);
      } else if (error.request) {
        // 请求已经成功发起，但没有收到响应
        // \`error.request\` 在浏览器中是 XMLHttpRequest 的实例，
        // 而在node.js中是 http.ClientRequest 的实例
        message.error("None response! Please retry.");
      } else {
        // 发送请求时出了点问题
        // message.error(error);
      }
    },
  },

  // 请求拦截器
  requestInterceptors: [
    (config: RequestOptions) => {
      // 获取 token
      const token = localStorage.getItem("token");

      // 检查是否需要添加 token
      const shouldAddToken =
        token && !EXCLUDE_PATHS.some((path) => config.url?.includes(path));

      // 对于 POST 请求，在请求体中添加 token 字段
      if (shouldAddToken && config.method?.toUpperCase() === "POST") {
        // 处理不同类型的请求体
        if (config.data instanceof FormData) {
          // 如果是 FormData，直接追加 token 字段
          config.data.append("token", token);
        } else if (typeof config.data === "object") {
          // 如果是对象，添加 token 属性
          config.data = {
            ...config.data,
            token: token,
          };
        } else if (typeof config.data === "string") {
          // 如果是字符串，尝试解析为 JSON
          try {
            const dataObj = JSON.parse(config.data);
            dataObj.token = token;
            config.data = JSON.stringify(dataObj);
          } catch (e) {
            // 如果不是 JSON 字符串，直接追加 token 参数
            config.data = `${config.data}&token=${token}`;
          }
        }
      }

      // 对于 GET 请求，在 URL 参数中添加 token
      if (shouldAddToken && config.method?.toUpperCase() === "GET") {
        const url = new URL(config.url || "", window.location.origin);
        url.searchParams.append("token", token);
        config.url = url.toString();
      }

      return config;
    },
  ],

  // 响应拦截器
  responseInterceptors: [
    (response) => {
      // 拦截响应数据，进行个性化处理
      const { data } = response as unknown as ResponseStructure;
      console.log(data, "datadata");
      // status 1 是
      if (!data?.success && data?.status === 9) {
        message.error("登录超时，即将跳转登录页面");
        setTimeout(() => {
          history.push(loginPath);
        }, 2000);
      }
      // else if (data?.success === false) {
      //   message.error("请求失败！");
      //   return
      // }
      return response;
    },
  ],
};
